package com.ikingtech.platform.service.label.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.label.api.LabelApi;
import com.ikingtech.framework.sdk.label.model.LabelAssignDTO;
import com.ikingtech.framework.sdk.label.model.LabelDTO;
import com.ikingtech.framework.sdk.label.model.LabelQueryParamDTO;
import com.ikingtech.framework.sdk.log.embedded.annotation.OperationLog;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.label.entity.LabelAssignDO;
import com.ikingtech.platform.service.label.entity.LabelDO;
import com.ikingtech.platform.service.label.exception.LabelExceptionInfo;
import com.ikingtech.platform.service.label.service.LabelAssignRepository;
import com.ikingtech.platform.service.label.service.LabelRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
@ApiController(value = "/label", name = "系统管理-标签管理", description = "系统管理-标签管理，")
public class LabelController implements LabelApi {

    private final LabelRepository repo;

    private final LabelAssignRepository assignService;

    /**
     * 添加标签
     * @param label 标签信息
     * @return 标签ID
     */
    @Override
    @OperationLog(value = "新增标签", dataId = "#_res.getData()")
    @Transactional(rollbackFor = Exception.class)
    public R<String> add(LabelDTO label) {
        // 将DTO转换为DO对象
        LabelDO entity = Tools.Bean.copy(label, LabelDO.class);
        // 生成标签ID
        entity.setId(Tools.Id.uuid());
        // 设置租户代码
        entity.setTenantCode(Me.tenantCode());
        // 保存标签信息到数据库
        this.repo.save(entity);
        return R.ok(entity.getId());
    }

    /**
     * 删除标签
     * @param id 标签ID
     * @return 删除结果
     */
    @Override
    @OperationLog(value = "删除标签")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> delete(String id) {
        // 删除标签
        this.repo.removeById(id);
        // 删除标签分配记录
        this.assignService.remove(Wrappers.<LabelAssignDO>lambdaQuery().eq(LabelAssignDO::getLabelId, id));
        return R.ok();
    }

    /**
     * 更新标签
     * @param label 标签信息
     * @return 更新结果
     */
    @Override
    @OperationLog(value = "更新标签")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> update(LabelDTO label) {
        // 检查标签是否存在
        if (!this.repo.exists(Wrappers.<LabelDO>lambdaQuery().eq(LabelDO::getId, label.getId()))) {
            throw new FrameworkException(LabelExceptionInfo.LABEL_NOT_FOUND);
        }
        // 更新标签信息
        this.repo.updateById(Tools.Bean.copy(label, LabelDO.class));
        return R.ok();
    }

    /**
     * 分配标签
     * @param labelAssign 标签分配DTO
     * @return 分配结果
     */
    @Override
    @OperationLog(value = "分配标签")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> assign(LabelAssignDTO labelAssign) {
        // 删除已有的标签分配记录
        this.assignService.remove(Wrappers.<LabelAssignDO>lambdaQuery()
                .eq(LabelAssignDO::getBusinessId, labelAssign.getBusinessId()));

        // 如果有标签ID列表，则批量保存标签分配记录
        if (Tools.Coll.isNotBlank(labelAssign.getLabelIds())) {
            this.assignService.saveBatch(Tools.Coll.convertList(labelAssign.getLabelIds(), labelId -> {
                LabelAssignDO entity = new LabelAssignDO();
                entity.setId(Tools.Id.uuid());
                entity.setBusinessId(labelAssign.getBusinessId());
                entity.setLabelId(labelId);
                return entity;
            }));
        }

        return R.ok();
    }

    /**
     * 分页查询标签列表
     *
     * @param queryParam 查询参数
     * @return 分页结果
     */
    @Override
    public R<List<LabelDTO>> page(LabelQueryParamDTO queryParam) {
        return R.ok(PageResult.build(this.repo.page(new Page<>(queryParam.getPage(), queryParam.getRows()),
                Wrappers.<LabelDO>lambdaQuery()
                        .like(Tools.Str.isNotBlank(queryParam.getName()), LabelDO::getName, queryParam.getName())
                        .orderByDesc(LabelDO::getCreateTime))).convert(entity -> Tools.Bean.copy(entity, LabelDTO.class)));
    }
}
